Nombres: Samuel Chavez F.

Conceptos básicos

En el análisis de reglas de asociación (Association Rules) y de conjuntos de objetos frecuentes (Frequent Itemset Analysis) tenemos varios conceptos que son importantes de recordar para entender correctamente lo que hacen las reglas de asociación. Tomemos como ejemplo los datos de compras en un supermercado.

Ojo que una regla de asociación no es una implicación lógica. Es decir, no necesariamente existe una relación de causalidad entre \(X\) e \(Y\), sino que de co-ocurrencia.

Existen distintas medidas de interés sobre itemsets y reglas. Entre las más importantes están support, confidence, y lift:

\[\sigma(X) = \text{# de veces que aparece }X \text{ en el dataset}\] \[\text{support}(X) = \frac{\sigma(X)}{N}\]

\[\text{support}(X \rightarrow Y) = \frac{\sigma(X \cup Y)}{N}\]

\[\text{confidence}(X \rightarrow Y) = \frac{\text{support}(X\rightarrow Y)}{\text{support}(X)} = \frac{\sigma(X \cup Y)}{\sigma(X)}\] \[\text{lift}(X\rightarrow Y) = \frac{\text{confidence}(X\rightarrow Y)}{\text{support}(Y)}\]

Donde \(N\) es la cantidad de transacciones (el tamaño del dataset).

Librerías

En R instale el paquete arules (son varias las dependencias, por lo tanto, se recomienda instalar antes de la sesión):

install.packages('arules')
install.packages('arulesViz')

Reglas de asociación en R

El objetivo es encontrar reglas de asociación interesantes a partir de un dataset de transacciones.

Para ejemplificar, usaremos un dataset pequeño.

library('arules')  # cargamos arules
## Loading required package: Matrix
## 
## Attaching package: 'arules'
## The following objects are masked from 'package:base':
## 
##     abbreviate, write
df <- read.transactions("http://users.dcc.uchile.cl/~jherrera/mineria/datasets/compras.csv", sep=",")

Nota: Cada línea del archivo csv corresponde a los productos de una compra.

Para ver el dataset, empleamos inspect:

inspect(df)   # para ver las reglas (si el dataset es largo, usar inspect(head(df))
##     items                                            
## [1] {Eggs, Kidney Beans, Milk, Nutmeg, Onion, Yogurt}
## [2] {Dill, Eggs, Kidney Beans, Nutmeg, Onion, Yogurt}
## [3] {Apple, Eggs, Kidney Beans, Milk}                
## [4] {Corn, Kidney Beans, Milk, Unicorn, Yogurt}      
## [5] {Corn, Eggs, Ice cream, Kidney Beans, Onion}

Para ver un resumen:

summary(df)
## transactions as itemMatrix in sparse format with
##  5 rows (elements/itemsets/transactions) and
##  11 columns (items) and a density of 0.4727273 
## 
## most frequent items:
## Kidney Beans         Eggs         Milk        Onion       Yogurt      (Other) 
##            5            4            3            3            3            8 
## 
## element (itemset/transaction) length distribution:
## sizes
## 4 5 6 
## 1 2 2 
## 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     4.0     5.0     5.0     5.2     6.0     6.0 
## 
## includes extended item information - examples:
##   labels
## 1  Apple
## 2   Corn
## 3   Dill

Itemsets más frecuentes

Para observar los itemsets más frecuentes, se definen umbrales (thresholds) de soporte, confianza, lift, etc. y se generan reglas cuya medida de interés sea mayor o igual a cada uno de estos umbrales.

Para esto usamos la función eclat. El parámetro supp filtra las reglas cuyo support sea mayor o igual a un valor. El parámetro maxlen indica la cantidad máxima de productos a considerar en un itemset. Por ejemplo, a continuación seleccionamos los itemsets que tengan support sobre 0.6, y que se compongan máximo de 10 objetos.

frequentItems <- eclat(df, parameter = list(supp = 0.6, maxlen = 10))
## Eclat
## 
## parameter specification:
##  tidLists support minlen maxlen            target  ext
##     FALSE     0.6      1     10 frequent itemsets TRUE
## 
## algorithmic control:
##  sparse sort verbose
##       7   -2    TRUE
## 
## Absolute minimum support count: 3 
## 
## create itemset ... 
## set transactions ...[11 item(s), 5 transaction(s)] done [0.00s].
## sorting and recoding items ... [5 item(s)] done [0.00s].
## creating bit matrix ... [5 row(s), 5 column(s)] done [0.00s].
## writing  ... [11 set(s)] done [0.00s].
## Creating S4 object  ... done [0.00s].
items.sorted <- sort(frequentItems, by="support")
inspect(items.sorted)
##      items                       support count
## [1]  {Kidney Beans}              1.0     5    
## [2]  {Eggs, Kidney Beans}        0.8     4    
## [3]  {Eggs}                      0.8     4    
## [4]  {Kidney Beans, Milk}        0.6     3    
## [5]  {Kidney Beans, Yogurt}      0.6     3    
## [6]  {Eggs, Kidney Beans, Onion} 0.6     3    
## [7]  {Kidney Beans, Onion}       0.6     3    
## [8]  {Eggs, Onion}               0.6     3    
## [9]  {Onion}                     0.6     3    
## [10] {Yogurt}                    0.6     3    
## [11] {Milk}                      0.6     3

También podemos graficar el top 10 de itemset más frecuentes:

 itemFrequencyPlot(df, topN=10, type="absolute", main="Item Frequency")

Algoritmo Apriori

Para generar reglas de asociación usamos el algoritmo Apriori, que es parte del paquete arules. En el siguiente código ejecutamos el algoritmo tal que busque reglas con un support de al menos 0.2 y confidence 0.3. Luego ordenamos según el lift de cada regla.

Nota: El parámetro minlen por defecto es 1, lo que significa que se crearán reglas con un solo elemento (es decir, un antecedente/LHS vacío) como {} => {Corn}. Ver documentación con help(“apriori”).

rules <- apriori(df, parameter=list(support=0.2, confidence=0.3))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.3    0.1    1 none FALSE            TRUE       5     0.2      1
##  maxlen target  ext
##      10  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 1 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[11 item(s), 5 transaction(s)] done [0.00s].
## sorting and recoding items ... [11 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 done [0.00s].
## writing ... [441 rule(s)] done [0.00s].
## creating S4 object  ... done [0.00s].
rules.sorted <- sort(rules, by="lift")
rules.sorted.first3 <- head(rules.sorted, 3)
inspect(rules.sorted.first3)
##     lhs               rhs         support confidence coverage lift count
## [1] {Corn, Milk}   => {Unicorn}   0.2     1          0.2      5    1    
## [2] {Corn, Yogurt} => {Unicorn}   0.2     1          0.2      5    1    
## [3] {Corn, Onion}  => {Ice cream} 0.2     1          0.2      5    1

El resultado de Apriori son las reglas de asociación cuyas asociaciones son más fuertes. Note que se entregan las medidas de support, confidence y lift.

Visualización de Reglas

Mediante la librería “arulesViz” se pueden graficar las reglas de asociación. Puede servir para tener una panorámica de cómo se distribuyen respecto a las distintas métricas (https://rdrr.io/cran/arulesViz/f/inst/doc/arulesViz.pdf).

Antes de visualizar las reglas, podemos filtrar aquellas que cumplen con algún criterio o seleccionar el top-n de reglas. Por ejemplo, seleccionar aquellas que tienen un confidence mayor a 0.8, o el top 10 de reglas con mayor confidence:

subrules <- rules[quality(rules)$confidence > 0.8]
top_subrules <- head(rules, n = 10, by = "confidence")

A continuación crearemos distintos tipos de gráficos para visualizar nuestras reglas ´rules´.

Gráfico de dispersión (Scatter plot)

A continuación un ejemplo sencillo usando “plot()”

library('arulesViz') 
## Warning: package 'arulesViz' was built under R version 4.2.2
plot(rules)
## To reduce overplotting, jitter is added! Use jitter = 0 to prevent jitter.

#Podemos añadir otras medidas y personalizar nuestros gráficos:
#plot(rules, measure = c("support", "lift"), shading = "confidence") 

También podemos crear una visualización interactiva usando engine='plotly'. Esta nos permite identificar las reglas y sus distintas métricas al pasar el cursor sobre cada punto.

plot(rules, engine='plotly')
## To reduce overplotting, jitter is added! Use jitter = 0 to prevent jitter.

También podemos usar el color de los puntos para indicar el “orden”, es decir, el número de elementos que contiene la regla. Esto nos daría una nueva dimensión que podemos analizar en conjunto con las métricas de los ejes x e y.

plot(rules, method = "two-key plot")
## To reduce overplotting, jitter is added! Use jitter = 0 to prevent jitter.

#Podemos hacerla interactiva y visualizar las reglas según el "orden" (haciendo clic sobre los colores a ocultar/mostrar)
#plot(rules, method = "two-key plot", engine='plotly') 

Gráfico de matriz agrupada

Gráfico de esferas con grupos de antecedentes como columnas y consecuentes como filas, donde el color y el tamaño representan las medidas de interés.

plot(rules, method = "grouped")

Grafos

En este gráfico los ítems y las reglas son representados como vértices conectados con aristas dirigidas. Las medidas de interés se representan mediante el color o el tamaño de los vértices. Esta visualización nos permite entender cómo se componen las reglas y cuáles items comparten entre ellas.

Para los siguientes gráficos seleccionamos las 20 reglas con mayor lift.

subrules <- head(rules, n = 20, by = "lift")
plot(subrules, method = "graph")

Referencias

Hahsler, Michael, and Sudheer Chelluboina. “Visualizing association rules: Introduction to the R-extension package arulesViz.” R project module 6 (2011): 223-238. https://rdrr.io/cran/arulesViz/f/inst/doc/arulesViz.pdf